/**
 * 唇语同步管理器 - 分析音频数据并生成唇语同步动画
 */
export class LipSyncManager {
    constructor(options = {}) {
        this.options = {
            // 音素映射配置
            visemeMapping: {
                'sil': 0,    // 静音
                'PP': 1,     // p, b, m
                'FF': 2,     // f, v
                'TH': 3,     // th
                'DD': 4,     // t, d, n, l
                'kk': 5,     // k, g
                'CH': 6,     // ch, j, sh
                'SS': 7,     // s, z
                'nn': 8,     // n, ng
                'RR': 9,     // r
                'aa': 10,    // a
                'E': 11,     // e
                'I': 12,     // i
                'O': 13,     // o
                'U': 14,     // u
                'W': 15      // w
            },
            
            // 中文音素映射
            chinesePhonemes: {
                'a': 'aa', 'o': 'O', 'e': 'E', 'i': 'I', 'u': 'U', 'ü': 'U',
                'ai': 'aa', 'ei': 'E', 'ao': 'aa', 'ou': 'O',
                'an': 'aa', 'en': 'E', 'ang': 'aa', 'eng': 'E',
                'b': 'PP', 'p': 'PP', 'm': 'PP', 'f': 'FF',
                'd': 'DD', 't': 'DD', 'n': 'DD', 'l': 'DD',
                'g': 'kk', 'k': 'kk', 'h': 'kk',
                'j': 'CH', 'q': 'CH', 'x': 'CH',
                'zh': 'CH', 'ch': 'CH', 'sh': 'CH', 'r': 'RR',
                'z': 'SS', 'c': 'SS', 's': 'SS',
                'w': 'W', 'y': 'I'
            },
            
            // 动画参数
            smoothing: 0.8,          // 平滑系数
            sensitivity: 1.0,        // 敏感度
            minVolume: 0.01,         // 最小音量阈值
            maxVolume: 0.8,          // 最大音量阈值
            frameRate: 60,           // 动画帧率
            
            ...options
        };
        
        // 当前状态
        this.currentViseme = 0;
        this.targetViseme = 0;
        this.currentIntensity = 0;
        this.targetIntensity = 0;
        
        // 音频分析
        this.audioContext = null;
        this.analyser = null;
        this.dataArray = null;
        this.source = null;
        
        // 动画数据
        this.visemeSequence = [];
        this.currentTime = 0;
        this.isPlaying = false;
        
        // 回调函数
        this.callbacks = {
            onVisemeChange: null,
            onIntensityChange: null,
            onSequenceComplete: null
        };
        
        this.init();
    }
    
    /**
     * 初始化唇语同步管理器
     */
    async init() {
        try {
            // 初始化音频上下文
            this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
            
            // 创建分析器
            this.analyser = this.audioContext.createAnalyser();
            this.analyser.fftSize = 2048;
            this.analyser.smoothingTimeConstant = this.options.smoothing;
            
            // 创建数据数组
            const bufferLength = this.analyser.frequencyBinCount;
            this.dataArray = new Uint8Array(bufferLength);
            
            console.log('LipSyncManager 初始化成功');
        } catch (error) {
            console.error('LipSyncManager 初始化失败:', error);
        }
    }
    
    /**
     * 连接音频源
     * @param {HTMLAudioElement} audioElement - 音频元素
     */
    connectAudio(audioElement) {
        if (!this.audioContext || !this.analyser) {
            console.error('音频上下文未初始化');
            return;
        }
        
        try {
            // 断开之前的连接
            if (this.source) {
                this.source.disconnect();
            }
            
            // 创建新的音频源
            this.source = this.audioContext.createMediaElementSource(audioElement);
            this.source.connect(this.analyser);
            this.analyser.connect(this.audioContext.destination);
            
            console.log('音频源连接成功');
        } catch (error) {
            console.error('音频源连接失败:', error);
        }
    }
    
    /**
     * 分析文本并生成音素序列
     * @param {string} text - 要分析的文本
     * @param {number} duration - 音频时长（秒）
     * @returns {Array} 音素序列
     */
    analyzeText(text, duration) {
        const phonemes = this.textToPhonemes(text);
        const sequence = this.generateVisemeSequence(phonemes, duration);
        
        this.visemeSequence = sequence;
        return sequence;
    }
    
    /**
     * 将文本转换为音素
     * @param {string} text - 输入文本
     * @returns {Array} 音素数组
     */
    textToPhonemes(text) {
        const phonemes = [];
        const chars = text.split('');
        
        for (let i = 0; i < chars.length; i++) {
            const char = chars[i];
            
            // 跳过标点符号和空格
            if (/[\s\.,!?;:]/.test(char)) {
                phonemes.push('sil');
                continue;
            }
            
            // 简单的中文音素映射
            const phoneme = this.mapChineseCharToPhoneme(char);
            phonemes.push(phoneme);
        }
        
        return phonemes;
    }
    
    /**
     * 映射中文字符到音素
     * @param {string} char - 中文字符
     * @returns {string} 音素
     */
    mapChineseCharToPhoneme(char) {
        // 这里是简化的映射，实际应用中可以使用更精确的拼音库
        const consonants = ['b', 'p', 'm', 'f', 'd', 't', 'n', 'l', 'g', 'k', 'h', 'j', 'q', 'x', 'zh', 'ch', 'sh', 'r', 'z', 'c', 's', 'w', 'y'];
        const vowels = ['a', 'o', 'e', 'i', 'u'];
        
        // 根据字符的Unicode范围进行简单分类
        const code = char.charCodeAt(0);
        
        if (code >= 0x4e00 && code <= 0x9fff) {
            // 中文字符，随机选择一个音素（实际应用中应该使用拼音库）
            const randomVowel = vowels[Math.floor(Math.random() * vowels.length)];
            return this.options.chinesePhonemes[randomVowel] || 'aa';
        }
        
        return 'sil';
    }
    
    /**
     * 生成音素序列
     * @param {Array} phonemes - 音素数组
     * @param {number} duration - 总时长
     * @returns {Array} 时间序列
     */
    generateVisemeSequence(phonemes, duration) {
        const sequence = [];
        const timePerPhoneme = duration / phonemes.length;
        
        for (let i = 0; i < phonemes.length; i++) {
            const phoneme = phonemes[i];
            const viseme = this.options.visemeMapping[phoneme] || 0;
            const startTime = i * timePerPhoneme;
            const endTime = (i + 1) * timePerPhoneme;
            
            sequence.push({
                viseme: viseme,
                phoneme: phoneme,
                startTime: startTime,
                endTime: endTime,
                intensity: phoneme === 'sil' ? 0 : 0.8
            });
        }
        
        return sequence;
    }
    
    /**
     * 开始播放唇语同步动画
     * @param {number} startTime - 开始时间
     */
    startPlayback(startTime = 0) {
        this.currentTime = startTime;
        this.isPlaying = true;
        this.startAnalysis();
        
        console.log('开始唇语同步播放');
    }
    
    /**
     * 停止播放
     */
    stopPlayback() {
        this.isPlaying = false;
        this.currentViseme = 0;
        this.currentIntensity = 0;
        
        console.log('停止唇语同步播放');
    }
    
    /**
     * 开始实时音频分析
     */
    startAnalysis() {
        if (!this.analyser || !this.dataArray) return;
        
        const analyze = () => {
            if (!this.isPlaying) return;
            
            // 获取音频数据
            this.analyser.getByteFrequencyData(this.dataArray);
            
            // 计算音频特征
            const features = this.calculateAudioFeatures(this.dataArray);
            
            // 更新当前时间
            this.currentTime += 1 / this.options.frameRate;
            
            // 根据时间序列更新音素
            this.updateVisemeFromSequence();
            
            // 根据音频特征调整强度
            this.updateIntensityFromAudio(features);
            
            // 触发回调
            this.triggerCallbacks();
            
            requestAnimationFrame(analyze);
        };
        
        analyze();
    }
    
    /**
     * 根据时间序列更新音素
     */
    updateVisemeFromSequence() {
        if (!this.visemeSequence.length) return;
        
        // 找到当前时间对应的音素
        const currentItem = this.visemeSequence.find(item => 
            this.currentTime >= item.startTime && this.currentTime < item.endTime
        );
        
        if (currentItem) {
            this.targetViseme = currentItem.viseme;
            this.targetIntensity = currentItem.intensity;
        } else {
            this.targetViseme = 0;
            this.targetIntensity = 0;
        }
        
        // 平滑过渡
        this.currentViseme = this.lerp(this.currentViseme, this.targetViseme, 0.3);
        this.currentIntensity = this.lerp(this.currentIntensity, this.targetIntensity, 0.2);
    }
    
    /**
     * 根据音频特征更新强度
     * @param {Object} features - 音频特征
     */
    updateIntensityFromAudio(features) {
        if (!features) return;
        
        // 根据音量调整强度
        const volume = Math.max(0, Math.min(1, features.volume));
        const audioIntensity = this.mapRange(
            volume, 
            this.options.minVolume, 
            this.options.maxVolume, 
            0, 
            1
        );
        
        // 结合序列强度和音频强度
        this.currentIntensity = Math.max(this.currentIntensity, audioIntensity * this.options.sensitivity);
    }
    
    /**
     * 计算音频特征
     * @param {Uint8Array} dataArray - 频率数据
     * @returns {Object} 音频特征
     */
    calculateAudioFeatures(dataArray) {
        let sum = 0;
        let max = 0;
        
        for (let i = 0; i < dataArray.length; i++) {
            sum += dataArray[i];
            max = Math.max(max, dataArray[i]);
        }
        
        const average = sum / dataArray.length;
        const volume = average / 255;
        
        return {
            average,
            max,
            volume,
            energy: Math.sqrt(sum / dataArray.length) / 255
        };
    }
    
    /**
     * 触发回调函数
     */
    triggerCallbacks() {
        if (this.callbacks.onVisemeChange) {
            this.callbacks.onVisemeChange(this.currentViseme, this.currentIntensity);
        }
        
        if (this.callbacks.onIntensityChange) {
            this.callbacks.onIntensityChange(this.currentIntensity);
        }
    }
    
    /**
     * 设置回调函数
     * @param {string} event - 事件名称
     * @param {Function} callback - 回调函数
     */
    on(event, callback) {
        if (this.callbacks.hasOwnProperty(`on${event.charAt(0).toUpperCase()}${event.slice(1)}`)) {
            this.callbacks[`on${event.charAt(0).toUpperCase()}${event.slice(1)}`] = callback;
        }
    }
    
    /**
     * 线性插值
     * @param {number} a - 起始值
     * @param {number} b - 目标值
     * @param {number} t - 插值系数
     * @returns {number} 插值结果
     */
    lerp(a, b, t) {
        return a + (b - a) * t;
    }
    
    /**
     * 映射数值范围
     * @param {number} value - 输入值
     * @param {number} inMin - 输入最小值
     * @param {number} inMax - 输入最大值
     * @param {number} outMin - 输出最小值
     * @param {number} outMax - 输出最大值
     * @returns {number} 映射后的值
     */
    mapRange(value, inMin, inMax, outMin, outMax) {
        return outMin + (outMax - outMin) * ((value - inMin) / (inMax - inMin));
    }
    
    /**
     * 获取当前音素信息
     * @returns {Object} 当前音素信息
     */
    getCurrentViseme() {
        return {
            viseme: Math.round(this.currentViseme),
            intensity: this.currentIntensity,
            time: this.currentTime
        };
    }
    
    /**
     * 销毁管理器
     */
    dispose() {
        this.stopPlayback();
        
        if (this.source) {
            this.source.disconnect();
        }
        
        if (this.audioContext) {
            this.audioContext.close();
        }
        
        // 清理回调
        Object.keys(this.callbacks).forEach(key => {
            this.callbacks[key] = null;
        });
        
        console.log('LipSyncManager 已销毁');
    }
}